package cn.com.libertymutual.sp.service.impl;

import java.nio.charset.Charset;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import com.beust.jcommander.internal.Lists;

import cn.com.libertymutual.core.base.dto.PrpLmAgent;
import cn.com.libertymutual.core.base.dto.ResponseBaseDto;
import cn.com.libertymutual.core.base.dto.TQueryLmAgentResponseDto;
import cn.com.libertymutual.core.redis.util.RedisUtils;
import cn.com.libertymutual.core.util.BeanUtilExt;
import cn.com.libertymutual.core.util.Constants;
import cn.com.libertymutual.core.util.Current;
import cn.com.libertymutual.core.util.DateUtil;
import cn.com.libertymutual.core.util.enums.CoreServiceEnum;
import cn.com.libertymutual.core.util.uuid.UUID;
import cn.com.libertymutual.core.web.ServiceResult;
import cn.com.libertymutual.core.web.util.RequestUtils;
import cn.com.libertymutual.sp.bean.TbSpInputConfig;
import cn.com.libertymutual.sp.bean.TbSpOrder;
import cn.com.libertymutual.sp.bean.TbSpSaleLog;
import cn.com.libertymutual.sp.bean.TbSpUser;
import cn.com.libertymutual.sp.dao.InputConfigDao;
import cn.com.libertymutual.sp.dao.OrderDao;
import cn.com.libertymutual.sp.dao.SpSaleLogDao;
import cn.com.libertymutual.sp.dao.UserDao;
import cn.com.libertymutual.sp.dto.InsureQuery;
import cn.com.libertymutual.sp.dto.PrpSalesPerson;
import cn.com.libertymutual.sp.dto.RateDto;
import cn.com.libertymutual.sp.dto.TPolicyDto;
import cn.com.libertymutual.sp.dto.TQueryPolicyResponseDto;
import cn.com.libertymutual.sp.dto.TQuerySalesResponseDto;
import cn.com.libertymutual.sp.dto.queryplans.CrossSalePlan;
import cn.com.libertymutual.sp.dto.savePlan.PropsalSaveRequestDto;
import cn.com.libertymutual.sp.service.api.BranchSetService;
import cn.com.libertymutual.sp.service.api.InsureService;
import cn.com.libertymutual.sp.service.api.PolicyService;
import cn.com.libertymutual.sp.service.api.ShopService;
import cn.com.libertymutual.sys.bean.SysServiceInfo;

@Service("InsureService")
public class InsureServiceImpl implements InsureService {
	private Logger log = LoggerFactory.getLogger(getClass());

	/** 上传文件同一目录 */
	@Value("${file.transfer.uploadImagesPath}")
	private String uploadImagesPath;

	@Resource
	private RedisUtils redis;
	@Resource
	private RestTemplate restTemplate;

	@Autowired
	private SpSaleLogDao spSaleLogDao;

	@Autowired
	private OrderDao orderDao;

	@Autowired
	private InputConfigDao inputConfigDao;

	@Autowired
	private ShopService shopService;

	@Resource
	private BranchSetService branchSetService;// 机构

	@Autowired
	private UserDao userDao;

	@Autowired
	private JdbcTemplate readJdbcTemplate;
	@Autowired
	private PolicyService policyService;

	@Override
	public ServiceResult uploadFfle(HttpServletRequest request, HttpServletResponse response, String imgFileName, List<MultipartFile> files,
			String proposalNo) {
		TbSpSaleLog saleLog = new TbSpSaleLog();
		StringBuilder logMsg = new StringBuilder();
		logMsg.append("queryData:" + imgFileName + "<br>" + proposalNo);
		Map map = (Map) redis.get(Constants.SYS_SERVICE_INFO);
		SysServiceInfo sysServiceInfo = (SysServiceInfo) map.get(CoreServiceEnum.UPLOAD_DOC_EFILING.getUrlKey());
		saleLog.setOperation(sysServiceInfo.getDescription());
		saleLog.setMark(proposalNo);
		saleLog.setOperation(sysServiceInfo.getDescription());
		List<TbSpOrder> orderList = orderDao.findProposalNo(proposalNo);
		ServiceResult sr = new ServiceResult();
		if (CollectionUtils.isEmpty(orderList)) {
			sr.setResult("没有查询到对应的订单！");
			sr.setFail();
			return sr;
		}
		TbSpOrder order = orderList.get(0);
		saleLog.setRequestTime(new Date());
		try {

			MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
			ByteArrayResource arrayResource = null;
			for (MultipartFile multipartFile : files) {
				logMsg.append("<br>FileName:" + multipartFile.getOriginalFilename() + "  SIZE:" + multipartFile.getSize());
				log.info(multipartFile.getOriginalFilename());
				try {
					// arrayResource = new ByteArrayResource( multipartFile.getBytes() );
					// , "attachment;filename="+new
					// String(multipartFile.getOriginalFilename().getBytes("UTF-8"), "ISO_8859_1")
					arrayResource = new ByteArrayResource(multipartFile.getBytes()) {
						@Override
						public String getFilename() throws IllegalStateException {
							/*
							 * try { return MimeUtility.encodeText(multipartFile.getOriginalFilename(),
							 * "UTF-8", null); } catch (UnsupportedEncodingException e) {
							 * e.printStackTrace(); }
							 */
							// TODO
							// 目前资料系统接收中文文件名会出现乱码，故给他重新生成一个文件名 bob.kuang 20170413
							///// return multipartFile.getOriginalFilename();

							if (multipartFile.getOriginalFilename().lastIndexOf('.') > 1) {

								return UUID.getUUIDString()
										+ multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf('.'));
							}
							return UUID.getUUIDString();
						}

					};

					params.add("files", new HttpEntity<ByteArrayResource>(arrayResource));
					// list.add(arrayResource);
				} catch (Exception e) {
					log.error(e.getMessage(), e);
				}

			}

			params.add("businessNo", proposalNo);
			logMsg.append("<br>businessNo:" + proposalNo);
			params.add("sort", Constants.UPLOAD_SORT_1);
			params.add("fromSystem", Constants.UPLOAD_FROM_SYSTEM);
			logMsg.append("<br>fromSystem:" + Constants.UPLOAD_FROM_SYSTEM);
			params.add("code", Constants.UPLOAD_CODE); // 254 Constants.UPLOAD_CODE
			logMsg.append("<br>code:" + Constants.UPLOAD_CODE);
			params.add("fileTitle", Constants.UPLOAD_FILE_TITLE); // 投保人/被保险人户口簿复印件 3505
			logMsg.append("<br>fileTitle:" + Constants.UPLOAD_FILE_TITLE);
			// params.add("files", fileList);
			params.add("partnerAccountCode", sysServiceInfo.getUserName());
			logMsg.append("<br>partnerAccountCode:" + sysServiceInfo.getUserName());
			String flowId = sysServiceInfo.getUserName() + DateUtil.dateFromat(new Date(), DateUtil.DATE_TIME_PATTERN3) + new Date().getTime();
			params.add("flowId", flowId);
			logMsg.append("<br>partnerAccountCode:" + flowId);
			params.add("operatorDate", DateUtil.getStringDate());

			params.add("agreementNo", sysServiceInfo.getTocken());
			logMsg.append("<br>agreementNo:" + sysServiceInfo.getTocken());
			HttpHeaders httpHeaders = RequestUtils.genEncryptHttpHeaders(sysServiceInfo.getUserName(), sysServiceInfo.getPassword());
			httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
			httpHeaders.setAcceptCharset(Lists.newArrayList(Charset.forName("UTF-8")));
			HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(params, httpHeaders);
			saleLog.setRequestData(logMsg.toString());
			ResponseBaseDto dto = new ResponseBaseDto();
			dto.setFlowId(sysServiceInfo.getUserName() + DateUtil.dateFromat(new Date(), DateUtil.DATE_TIME_PATTERN3));
			dto.setUuId(Current.uuid.get());
			ResponseEntity<ServiceResult> responseEntity = restTemplate.exchange(sysServiceInfo.getUrl(), HttpMethod.POST, httpEntity,
					ServiceResult.class);
			log.info(responseEntity.toString());
			saleLog.setResponseData(BeanUtilExt.toJsonString(responseEntity));
			ServiceResult resRs = responseEntity.getBody();
			if (ServiceResult.STATE_SUCCESS != resRs.getState()) {
				sr.setFail();
				spSaleLogDao.save(saleLog);
				sr.setResult("上传文件失败");
				orderDao.delete(order);
				return sr;
			}
			// if(responseEntity.getStatusCode()) {
			//
			// }

		} catch (Exception e) {
			sr.setFail();
			saleLog.setResponseData(e.toString() + "本地上传文件失败!");
			spSaleLogDao.save(saleLog);
			sr.setResult("上传文件失败");
			orderDao.delete(order);
			log.error(e.toString());
			return sr;
		}
		order.setStatus(Constants.TBSPORDER_STATUS_NO_PAY);
		// saleLog.setResponseData("文件上传成功!");
		spSaleLogDao.save(saleLog);
		orderDao.save(order);
		sr.setSuccess();
		return sr;
	}

	@Override
	public ServiceResult getConfigData(String inputId) {
		ServiceResult sr = new ServiceResult();
		TbSpInputConfig que = inputConfigDao.findByInputId(inputId);
		if (null == que) {
			sr.setFail();
			sr.setResult("没有查询到对应的信息！");
			return sr;
		}
		sr.setSuccess();
		sr.setResult(que);

		return sr;
	}

	@Override
	public TbSpOrder setInsureBrachCode(TbSpOrder order, InsureQuery insureQuery, PropsalSaveRequestDto requestDto) {

		String braCode = "";
		String userCode = "";
		TbSpUser user = requestDto.getUser();
		if (StringUtils.isNotBlank(insureQuery.getRefereeId())) {
			userCode = insureQuery.getRefereeId();
		} else if (StringUtils.isNotBlank(user.getUserCode())) {
			userCode = user.getUserCode();
		}
		if (!StringUtils.isNotBlank(userCode) && !userCode.startsWith("WX") && !userCode.startsWith("BS") && !userCode.startsWith("wx")
				&& !userCode.startsWith("bs")) {
			userCode = "";
		}
		if (StringUtils.isNotBlank(user.getUserCode())) {
			braCode = branchSetService.getUserCodeBranchCode(userCode);
		}
		if (StringUtils.isBlank(braCode)) {
			braCode = requestDto.getHotarea().getBranchCode();
		}
		order.setBranchCode(braCode); // 分公司

		return order;
	}

	@Override
	public TbSpOrder setAgrInfo(TbSpOrder order, String agre, String refId) throws Exception {
		TQueryLmAgentResponseDto responseDto = shopService.findAgreementNo(agre);
		// 业务关系代码列表为空，默认请使用第一条数据
		List<PrpLmAgent> prpLmAgentList = responseDto.getPrpLmAgentList();
		if (CollectionUtils.isNotEmpty(prpLmAgentList)) {
			PrpLmAgent prpLmAgent = prpLmAgentList.get(0);
			order = setCommCode(order, refId, prpLmAgent.getBranch());

			// order.setComCode(prpLmAgent.getBranch());
			// order.set
			order.setChannelType(prpLmAgent.getAlternate8());
			order.setCustomName(prpLmAgent.getAlternate9());
			order.setBranchOffice(prpLmAgent.getChannelName());
			order.setAgentName(prpLmAgent.getAgentName());
			order.setSalesmanName(prpLmAgent.getHandlerName());
			order.setSalesmanCode(prpLmAgent.getHandlerCode());
		}
		return order;
	}

	@Override
	public TbSpOrder setCommCode(TbSpOrder order, String userCode, String defaultCode) {
		// TbSpUser user = null;
		// if (StringUtils.isNotBlank(userCode)) {
		// userCode = branchSetService.getUserCodeBranchCode(userCode);
		// user = userDao.findByUserCode(userCode);
		// }
		// if (null != user && StringUtils.isNotBlank(user.getComCode())) {
		// order.setComCode(user.getComCode());
		// } else {
		// order.setComCode(defaultCode);
		// }
		if (StringUtils.isNotBlank(userCode)) {
			order.setComCode(userCode);
		} else {
			order.setComCode(defaultCode);
		}

		return order;
	}

	@Override
	public String getSaleCode(String agre, String saleNumber) throws Exception {
		ServiceResult sale = new ServiceResult(Constants.SYS_ERROR_MSG, ServiceResult.STATE_EXCEPTION);
		sale = branchSetService.getSaleName(agre);
		if (sale.getState() == ServiceResult.STATE_SUCCESS) {
			TQuerySalesResponseDto dto = (TQuerySalesResponseDto) sale.getResult();
			List<PrpSalesPerson> persons = dto.getSealesPersos();
			for (int i = 0; i < persons.size(); i++) {
				PrpSalesPerson pe = persons.get(i);
				if (saleNumber.equals(pe.getSaleVocationCardNo())) {
					return pe.getSaleName();
				}
			}
		}
		return "";
	}

	@Override
	public TbSpOrder setOrderInitData(TbSpOrder order, InsureQuery insureQuery) {
		if (null != insureQuery.getIsNeedUpload() && insureQuery.getIsNeedUpload()) {
			order.setStatus(Constants.TBSPORDER_STATUS_INVALID); // 订单状态
		} else {
			order.setStatus(Constants.TBSPORDER_STATUS_NO_PAY); // 订单状态
		}
		order.setRiskName(insureQuery.getRiskName()); // 险种名字
		order.setRiskCode(insureQuery.getProRiskCode());
		order.setPlanRiskCode(insureQuery.getRisk());
		order.setPlanCode(insureQuery.getPlanId()); // 获得计划代码
		order.setPlanName(insureQuery.getPlanName()); // 获得计划名称
		order.setProductId(insureQuery.getProductId()); // 产品id
		order.setProductName(insureQuery.getProductName()); // 产品名称
		order.setCallBackUrl(insureQuery.getCallBackUrl());
		order.setSingleMember(insureQuery.getSingleMember());
		order.setSuccessfulUrl(insureQuery.getSuccessfulUrl());
		order.setDealUuid(insureQuery.getDealUid());
		order.setInsureCity(insureQuery.getCity());
		if (StringUtils.isBlank(insureQuery.getShareUid())) {
			order.setShareUid("henghua");
		} else {
			order.setShareUid(insureQuery.getShareUid());
		}
		order.setClauseUrl(""); // 条款url
		order.setCreateTime(new Date()); // 订单创建时间
		order.setUpdateTime(new Date()); // 更细那时间
		order.setRemark(""); // 备注
		order.setPayWay("7"); // 支付方式
		order.setHouseAddress(""); // 房屋地址
		order.setPaymentNo(""); // 支付流水号
		order.setPolicyNo("");// 投保单号
		order.setPayDate(null); // 支付日期，回掉的时候设置
		order.setTravelDestination("");
		order.setSaleType(""); // 销售渠道
		order.setAddress("");
		return order;
	}

	@Override
	public TbSpOrder setQueryInfo(TbSpOrder order, String proposalNo) {
		TQueryPolicyResponseDto responseDto = policyService.queryDetail(proposalNo);
		if (null != responseDto && CollectionUtils.isNotEmpty(responseDto.getPolicys())) {
			TPolicyDto tPolicyDto = responseDto.getPolicys().get(0);
			order.setAmount(Double.valueOf(tPolicyDto.getSumpremium()));// 总保费
			order.setRiskName(tPolicyDto.getRiskcname());// 险种名称
			order.setPlanRiskCode(tPolicyDto.getRiskcode());
			order.setUpdateTime(new Date());
			order.setProductName(tPolicyDto.getRiskcname());
			order.setAmount(Double.parseDouble(tPolicyDto.getSumpremium()));
			order.setRiskName(tPolicyDto.getRiskcname());
			order.setPlanName(tPolicyDto.getRiskcname());
			// order.setStartDate(DateUtil.strToDate(tPolicyDto.getStartdate()));
			// order.setEndDate(DateUtil.strToDate(tPolicyDto.getEnddate()));
			try {
				Date startDate = (Date) new SimpleDateFormat(DateUtil.DATE_TIME_PATTERN).parseObject(tPolicyDto.getStartdate());
				order.setStartDate(startDate);
				Date endDate = (Date) new SimpleDateFormat(DateUtil.DATE_TIME_PATTERN).parseObject(tPolicyDto.getEnddate());
				order.setEndDate(endDate);
			} catch (ParseException e) {
				e.printStackTrace();
			}
			order.setApplicantName(tPolicyDto.getAppliname());// 投保人姓名
			order.setIdNo(tPolicyDto.getAppliIdentifynumber());// 投保人证件号
		}
		return order;
	}

	@Override
	public List<String> topUser(String userCode, List<String> upNumbers) {

		TbSpUser user = userDao.findByUserCode(userCode);
		if (null != user) {
			upNumbers.add(upNumbers.size(), user.getUserCode());
			topUser(user.getComCode(), upNumbers);
		}
		return upNumbers;
	}

	@Override
	public RateDto getLevelRate(String userCode) {
		RateDto raDto = new RateDto();
		Double rate = 1.0;
		TbSpUser user = userDao.findByUserCode(userCode);
		if (null != user
				&& (Constants.USER_REGISTER_TYPE_1.equals(user.getRegisterType()) || Constants.USER_REGISTER_TYPE_2.equals(user.getRegisterType()))) {
			List<String> userTopList = topUser(userCode, new ArrayList<String>());
			TbSpUser userLevel = null;
			// 设置下级是否显示佣金比例
			if (Strings.isNotBlank(user.getComCode())) {
				TbSpUser upUser = userDao.findByUserCode(user.getComCode());
				if (upUser != null && "0".equals(upUser.getCanScore())) {
					rate = 0.0;
				}
			}
			// 如果不显示就没必要去查找层级算比例
			if (rate != 0.0) {
				for (int i = 0; i < userTopList.size(); i++) {
					if (!userCode.equals(userTopList.get(i))) {
						userLevel = userDao.findByUserCode(userTopList.get(i));
						Double rateLeven = userLevel.getBaseRate();
						if (rateLeven != null && rateLeven != 0.0) {
							rate = rate * rateLeven;
						}
					}
				}
			}
			if (CollectionUtils.isNotEmpty(userTopList) && userTopList.size() > 1) {
				userCode = userTopList.get(userTopList.size() - 1);
			}
		} else {
			if (user != null && !Constants.USER_TYPE_2.equals(user.getUserType()) && !Constants.USER_TYPE_5.equals(user.getUserType())) {
				rate = 0.0;
			}
		}
		raDto.setUserCode(userCode);
		raDto.setRate(rate);
		return raDto;
	}

	@Override
	public ServiceResult getFindAllFriend(String userCode, String type, String sort, String serch) {
		ServiceResult sr = new ServiceResult();
		StringBuilder sb = new StringBuilder();
		Boolean isFind = false;
		List<Map<String, Object>> list = null;
		if (StringUtils.isBlank(userCode)) {
			sr.setFail();
			return sr;
		}
		sb.append(
				"SELECT u.USER_CODE as userCode,u.HEAD_URL as headUrl,u.USER_NAME as userName ,DATE_FORMAT(u.REGISTE_DATE, '%Y-%c-%d %H:%i:%s') as resDate,(SELECT COUNT(*)  FROM tb_sp_order WHERE (Referee_ID = u.USER_CODE OR Referee_ID = u.USER_CODE_BS OR ( Referee_ID = '' AND USER_ID = u.USER_CODE ) OR ( Referee_ID = '' AND USER_ID = u.USER_CODE_BS ) ) AND STATUS IN ('1', '3') AND Policy_No <> '' ) AS orderCount, ( SELECT 	SUM(AMOUNT) FROM 	tb_sp_order WHERE ( 	Referee_ID = u.USER_CODE 	OR Referee_ID = u.USER_CODE_BS 	OR ( 		Referee_ID = '' 		AND USER_ID = u.USER_CODE 	) 	OR ( 		Referee_ID = '' 		AND USER_ID = u.USER_CODE_BS 	) ) AND STATUS IN ('1', '3') AND Policy_No <> '' ) AS orderAmout FROM tb_sp_user AS u WHERE    u.COM_CODE = ? AND u.STATE = '1' AND ( u.REGISTER_TYPE = '0' OR u.REGISTER_TYPE ='2') ");
		// String findSql = "SELECT u.USER_CODE as userCode,u.HEAD_URL as
		// headUrl,u.USER_NAME as userName ,DATE_FORMAT(u.REGISTE_DATE, '%Y-%c-%d
		// %h:%i:%s') as resDate,(SELECT COUNT(*) FROM tb_sp_order WHERE (Referee_ID =
		// u.USER_CODE OR Referee_ID = u.USER_CODE_BS OR ( Referee_ID = '' AND USER_ID =
		// u.USER_CODE ) OR ( Referee_ID = '' AND USER_ID = u.USER_CODE_BS ) ) AND
		// STATUS IN ('1', '3') AND Policy_No <> '' ) AS orderCount, ( SELECT
		// SUM(AMOUNT) FROM tb_sp_order WHERE ( Referee_ID = u.USER_CODE OR Referee_ID =
		// u.USER_CODE_BS OR ( Referee_ID = '' AND USER_ID = u.USER_CODE ) OR (
		// Referee_ID = '' AND USER_ID = u.USER_CODE_BS ) ) AND STATUS IN ('1', '3') AND
		// Policy_No <> '' ) AS orderAmout FROM tb_sp_user AS u WHERE u.COM_CODE = ? AND
		// u.STATE = '1' AND ( u.REGISTER_TYPE = '0' OR u.REGISTER_TYPE ='2') ";

		if (StringUtils.isNotBlank(serch)) {
			isFind = true;
			serch = "%" + serch + "%";
			sb.append(" And  u.USER_NAME like ? ");
		}

		if (StringUtils.isNotBlank(type)) {
			sb.append(" order by " + type + " " + sort);
		}

		if (isFind) {
			list = readJdbcTemplate.queryForList(sb.toString(), new Object[] { userCode, serch });
		} else {
			list = readJdbcTemplate.queryForList(sb.toString(), new Object[] { userCode });
		}
		sr.setSuccess();
		sr.setResult(list);
		return sr;
	}

	@Override
	public TbSpOrder setCrossSaleOrderInitData(TbSpOrder order, CrossSalePlan crossSalePlan) {
		order.setAmount(Double.valueOf(crossSalePlan.getPlanPrice()));// 总保费
		if ("3105".equals(crossSalePlan.getProCode())) {
			order.setRiskName("家财险");// 险种名称
			order.setProductName("安途全球保");
		} else {
			order.setRiskName("意外险");// 险种名称
			order.setProductName("安行天下");
		}
		order.setPlanRiskCode(crossSalePlan.getProCode());
		order.setUpdateTime(new Date());
		// order.setProductName(crossSalePlan.getProName());
		order.setPlanName(crossSalePlan.getPlanName());
		order.setAmount(Double.parseDouble(crossSalePlan.getPlanPrice()));
		// order.setStartDate(DateUtil.strToDate(tPolicyDto.getStartdate()));
		// order.setEndDate(DateUtil.strToDate(tPolicyDto.getEnddate()));
		// order.setApplicantName(tPolicyDto.getAppliname());// 投保人姓名
		// order.setIdNo(tPolicyDto.getAppliIdentifynumber());// 投保人证件号
		return order;
	}

}
